﻿using System;
using System.Collections.Generic;
using com.yoozoo.gta.Extension;
using UnityEngine;
using Yoozoo.Mars.Got;

namespace Yoozoo.Gameplay.RTS
{
    public class HudManager
    {
        public const int MarchHudLod0 = 0;
        public const int MarchHudLod1 = 1;
        public const int MonsterHudLod0 = 2;
        public const int MonsterHudLod1 = 3;
        public const int MarchHudLod1Point = 4;
        public const int CommanderHead = 5;
        public const int ComCommander = 6;
        public const int MonsterRadarIcon = 7;
        public const int LohaHudLod0 = 8;
        public const int LohaHudLod1 = 9;
        public const int MapPoliceHpBarLod0 = 10;
        public const int BaseArmyInfo = 11;
        public const int WonderNpc = 12;
        public const int SmuggleHudLod0 = 13;
        public const int SmuggleHudLod1 = 14;
        public const int PracticeBossHud = 15;
        public const int BkiArmyLod0 = 16;
        public const int BkiArmyLod1 = 17;
        public const int CargoTruckLod0 = 18;
        public const int CargoTruckLod1 = 19;
        public const int WorldBossHud = 20;
        public const int TradeTruckLod1 = 21;
        public const int TsanTip = 22;
        public const int NewYearHudLod0 = 23;
        
        readonly List<HudPool> hudPoolList = new List<HudPool>();
        public const int BaseSortLayer = 100;
        private int maxHudLayerNum = 500;
        private int _currentLayerIndex = 0;
        private int layerMaxMinDif = 10;

        private const int HudPoolNum = 128;
        private const int SmugglerNpcPoolNum = 16;
        private const int WonderNpcPoolNum = 64;
        private const int CargoTruckPoolNum = 16;
        private const int SimpleHudPoolNum = 128;
        private readonly List<MarchHud> marchHudPool = new List<MarchHud>(HudPoolNum);
        
        private readonly List<MonsterHud> monsterHudPool = new List<MonsterHud>(HudPoolNum);
        
        private readonly List<WonderNpcHud> wonderNpcHudPool = new List<WonderNpcHud>(WonderNpcPoolNum);

        private readonly List<CargoTruckHud> cargoTruckHudPool = new List<CargoTruckHud>(CargoTruckPoolNum);

        private readonly List<SmugglerHud> smugglerNpcHudPool = new List<SmugglerHud>(SmugglerNpcPoolNum);
        private HudRageEffectPool hudRageEffectPool;
        
        public int GetCurrentBaseLayer()
        {
            if (_currentLayerIndex >= maxHudLayerNum)
            {
                _currentLayerIndex = 0;
            }
            return BaseSortLayer + layerMaxMinDif * ++_currentLayerIndex;
        }
        private readonly string[] hudPaths = new[]
        {
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/ArmyInfo.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/MarchHudLOD1.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/MonsterHudLOD0.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/MonsterHudLOD1.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/MarchHudLOD1Point.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/CommanderHead.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/ComCommander.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/MonsterRadarIcon.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/LohaHudLOD0.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/LohaHudLOD1.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/MapPoliceHpBarLod0.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/BaseArmyInfo.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/WonderNpcHudLOD0.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/SmuggleHudLod0.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/SmuggleHudLod1.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/PracticeBossHud.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/BkiArmyLod0.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/BkiArmyLod1.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/CargoTruckHudLod0.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/CargoTruckHudLod1.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/WorldBossHud.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/TruckHudLOD1.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/TsanTip.prefab",
            "Assets/ResourcesAssets/Prefabs/UI/SandBox/NewYearHudLod0.prefab",
        };

        public void InitAndLoadHudPrefab(Transform poolRoot,Action CompleteFunc)
        {
            calltime = 0;
            int capacity = 200;
            int initNum = 50;
    
            hudPoolList.Add(new HudPool(initNum, capacity, hudPaths[MarchHudLod0], poolRoot, true, capacity, 5, 5, MarchHudLod0,true));//部队简略信息
            hudPoolList.Add(new HudPool(5, 5, hudPaths[MarchHudLod1], poolRoot, false, 5, 0, float.MaxValue, MarchHudLod1,true));//部队LOD1信息只有我方部队存在
            hudPoolList.Add(new HudPool(initNum, capacity, hudPaths[MonsterHudLod0], poolRoot, true, capacity, 5, 5, MonsterHudLod0));//野怪lod1信息
            hudPoolList.Add(new HudPool(initNum, capacity, hudPaths[MonsterHudLod1], poolRoot, true, capacity, 5, 5, MonsterHudLod1));
            hudPoolList.Add(new HudPool(initNum, capacity, hudPaths[MarchHudLod1Point], poolRoot, true, capacity, 5, 5, MarchHudLod1Point));
            hudPoolList.Add(new HudPool(10, 20, hudPaths[CommanderHead], poolRoot, true, 5, 1, 1, CommanderHead));

            hudPoolList.Add(new HudPool(5, 5, hudPaths[ComCommander], poolRoot, true, 5, 1, 1, ComCommander));
            hudPoolList.Add(new HudPool(5, 5, hudPaths[MonsterRadarIcon], poolRoot, true, 5, 1, 1, MonsterRadarIcon));
            
            hudPoolList.Add(new HudPool(5, 5, hudPaths[LohaHudLod0], poolRoot, true, 5, 1, 1, LohaHudLod0));
            hudPoolList.Add(new HudPool(5, 5, hudPaths[LohaHudLod1], poolRoot, true, 5, 1, 1, LohaHudLod1));
            hudPoolList.Add(new HudPool(1, 5, hudPaths[MapPoliceHpBarLod0], poolRoot, true, 1, 1, 1, MapPoliceHpBarLod0));
            
            hudPoolList.Add(new HudPool(10, 20, hudPaths[BaseArmyInfo], poolRoot, true, 5, 1, 1, BaseArmyInfo));
            hudPoolList.Add(new HudPool(5, 5, hudPaths[WonderNpc], poolRoot, true, 5, 1, 1, WonderNpc));
            hudPoolList.Add(new HudPool(5, 5, hudPaths[SmuggleHudLod0], poolRoot, true, 5, 1, 1, SmuggleHudLod0,true));
            hudPoolList.Add(new HudPool(5, 5, hudPaths[SmuggleHudLod1], poolRoot, true, 5, 1, 1, SmuggleHudLod1));

            hudPoolList.Add(new HudPool(1, 1, hudPaths[PracticeBossHud], poolRoot, true, 5, 1, 1, PracticeBossHud));

            hudPoolList.Add(new HudPool(1, 1, hudPaths[BkiArmyLod0], poolRoot, true, 5, 1, 1, BkiArmyLod0));
            hudPoolList.Add(new HudPool(1, 1, hudPaths[BkiArmyLod1], poolRoot, true, 5, 1, 1, BkiArmyLod1));

            hudPoolList.Add(new HudPool(1, 1, hudPaths[CargoTruckLod0], poolRoot, true, 5, 1, 1, CargoTruckLod0));
            hudPoolList.Add(new HudPool(1, 1, hudPaths[CargoTruckLod1], poolRoot, true, 5, 1, 1, CargoTruckLod1));

            hudPoolList.Add(new HudPool(1, 1, hudPaths[WorldBossHud], poolRoot, true, 5, 1, 1, WorldBossHud));
            hudPoolList.Add(new HudPool(1, 1, hudPaths[TradeTruckLod1], poolRoot, true, 5, 1, 1, TradeTruckLod1));
            
            hudPoolList.Add(new HudPool(10, 10, hudPaths[TsanTip], poolRoot, true, 5, 1, 1, TsanTip));
            
            hudPoolList.Add(new HudPool(1, 1, hudPaths[NewYearHudLod0], poolRoot, true, 1, 1, 1, NewYearHudLod0, true, true));
            
            this._CompleteFunc = CompleteFunc;
            InitHudPool();
            InitHudEffectPool(poolRoot);
            hudRageEffectPool.StartLoad(5,null);

            foreach (var hudPool in hudPoolList)
            {
                hudPool.StartLoad(hudPool.initNum,CheckInitComplete);
            }
            
        }

        private void InitHudPool()
        {
            for (int i = 0; i < HudPoolNum; i++)
            {
                marchHudPool.Add(new MarchHud());
            }

            for (int i = 0; i < HudPoolNum; i++)
            {
                monsterHudPool.Add(new MonsterHud());
            }
            
            for (int i = 0; i < WonderNpcPoolNum; i++)
            {
                wonderNpcHudPool.Add(new WonderNpcHud());
            }

            for (int i = 0; i < CargoTruckPoolNum; i++)
            {
                cargoTruckHudPool.Add(new CargoTruckHud());
            }
        }

        private void InitHudEffectPool(Transform poolRoot)
        {
            hudRageEffectPool = new HudRageEffectPool(5, 100, poolRoot, true, 100, 5, 5);
        }
        
        public MarchHud GetMarchHudClsFromPool()
        {
            MarchHud hud;
            if (marchHudPool.Count == 0)
            {
                hud = new MarchHud();
            }
            else
            {
                hud = marchHudPool[marchHudPool.Count - 1];
                marchHudPool.RemoveAt(marchHudPool.Count - 1);
            }
            return hud;
        }

        public PractiseMarchHud GetPractiseHudClsFromPool()
        {
            PractiseMarchHud hud = new PractiseMarchHud();
            return hud;
        }
        
        public WorldBossHud GetWorldBossHudClsFromPool()
        {
            WorldBossHud hud = new WorldBossHud();
            return hud;
        }

        public MonsterHud GetMonsterHudClsFromPool()
        {
            MonsterHud hud;
            if (monsterHudPool.Count == 0)
            {
                hud = new MonsterHud();
            }
            else
            {
                hud = monsterHudPool[monsterHudPool.Count - 1];
                monsterHudPool.RemoveAt(monsterHudPool.Count - 1);
            }
            return hud;
        }
        
        public WonderNpcHud GetWonderNpcHudClsFromPool()
        {
            WonderNpcHud hud;
            if (wonderNpcHudPool.Count == 0)
            {
                hud = new WonderNpcHud();
            }
            else
            {
                hud = wonderNpcHudPool[wonderNpcHudPool.Count - 1];
                wonderNpcHudPool.RemoveAt(wonderNpcHudPool.Count - 1);
            }
            return hud;
        }

        public CargoTruckHud GetCargoTruckHudClsFromPool()
        {
            CargoTruckHud hud;
            if (cargoTruckHudPool.Count == 0)
            {
                hud = new CargoTruckHud();
            }
            else
            {
                hud = cargoTruckHudPool[cargoTruckHudPool.Count - 1];
                cargoTruckHudPool.RemoveAt(cargoTruckHudPool.Count - 1);
            }
            return hud;
        }

        public SmugglerHud GetSmugglerNpcHudClsFromPool()
        {
            SmugglerHud hud;
            if (smugglerNpcHudPool.Count == 0)
            {
                hud = new SmugglerHud();
            }
            else
            {
                hud = smugglerNpcHudPool[smugglerNpcHudPool.Count - 1];
                smugglerNpcHudPool.RemoveAt(smugglerNpcHudPool.Count - 1);
            }
            return hud;
        }
        public PracticeBossHud GetPracticeBossHudClsFromPool()
        {
            PracticeBossHud hud = new PracticeBossHud();
            return hud;
        }
        public void RecoverMarchHudCls(MarchHud hud)
        {
            marchHudPool.Add(hud);
        }

        public void RecoverMonsterHudCls(MonsterHud hud)
        {
            monsterHudPool.Add(hud);
        }

        public void RecoverWonderNpcHudCls(WonderNpcHud hud)
        {
            wonderNpcHudPool.Add(hud);
        }
        public void RecoverSmugglerNpcHudCls(SmugglerHud hud)
        {
            smugglerNpcHudPool.Add(hud);
        }

        private Action _CompleteFunc;

        private int calltime = 0; 
        public void CheckInitComplete(string path,bool result)
        {
            if (!result)
            {
                UnityEngine.Debug.LogErrorFormat("加载资源path = {0} 失败",path);
            }

            calltime++;
            ArmyManager.loadingCallBack?.Invoke(calltime, hudPoolList.Count, "rtshud");
            if (calltime == hudPoolList.Count && _CompleteFunc!=null)
            {
                _CompleteFunc.Invoke();
                _CompleteFunc = null;
            }
        }
        public bool IsInitComplete()
        {
            int length = hudPoolList.Count;
            bool result = true;
            for (int i = 0; i < length; i++)
            {
                result = result && hudPoolList[i].InitComplete;
            }

            return result;
        }
        public GameObject GetHud(int hudType)
        {
            if(hudType < 0 || hudType >= hudPoolList.Count)
                throw new ArgumentOutOfRangeException(nameof(hudType));

            var hudPool = hudPoolList[hudType];
            return hudPool.GetItem();
        }

        public void RecoverHud(int hudType, GameObject hud)
        {
            if (hud == null || !hud.Valid())
            {
                Debug.LogError(hudType+" hud已经被销毁了");
                return;
            }
            if (hudType < 0 || hudType >= hudPoolList.Count)
                throw new ArgumentOutOfRangeException(nameof(hudType));

            var hudPool = hudPoolList[hudType];
            hudPool.RecoverItem(hud);
        }

        public HudRageEffect GetHudRageEffect()
        {
            return hudRageEffectPool.GetItem();
        }

        public void RecoverHudRageEffect(HudRageEffect rageEffect)
        {
            if (hudRageEffectPool != null)
            {
                hudRageEffectPool.RecoverItem(rageEffect);
            }
            else
            {
                GameObject.Destroy(rageEffect.gameObject);
            }
        }

        public void Dispose()
        {
            foreach (var hudPool in hudPoolList)
            {
                hudPool.Dispose();
            }

            hudPoolList.Clear();
            hudRageEffectPool.Dispose();
        }
    }
}
